import { Link, Warning } from '@brillout/docpress'

You can programmatically trigger <Link href="/cli">CLI commands</Link> by using following functions:
 - <Link href="#dev" />
 - <Link href="#build" />
 - <Link href="#preview" />
 - <Link href="#prerender" />

Common use cases:
 - Writing a custom build script for adding post-processing.
 - Building your own CLI in the context of <Link href="/build-your-own-framework" noBreadcrumb />.


## `dev()`

Start the development server:

```ts
import { dev } from 'vike/api'

console.log('Starting development server...')

const { viteServer, viteConfig } = await dev()
await viteServer.listen()
viteServer.printUrls()
viteServer.bindCLIShortcuts({ print: true })

const { port } = viteConfig.server
console.log(`Development server is ready at http://localhost:${port}`)
```

Return & options:

```ts
const {
  viteConfig, // Resolved Vite configuration
  viteServer // Vite's development server
} = await dev({
  vikeConfig, // Vike configuration (optional)
  viteConfig // Vite configuration (optional)
})

// You can access the globalContext object:
import { getGlobalContext } from 'vike'
const globalContext = await getGlobalContext()
```

See:
- <Link href='#option-vikeconfig' />
- <Link href='#option-viteconfig' />
- <Link href='#access-globalcontext' />

Vite types:
- The type of `viteConfig` is [`ResolvedConfig`](https://vite.dev/guide/api-javascript.html#resolvedconfig)
- Vite's development server: [`const viteServer = createServer()`](https://vite.dev/guide/api-javascript.html#createserver)


## `build()`

Build for production:

```ts
import { build } from 'vike/api'

console.log('Building app...')
await build()
console.log('Build is done')
```

Return & options:

```ts
await build({
  vikeConfig, // Vike configuration (optional)
  viteConfig // Vite configuration (optional)
})

// You can access the globalContext object:
import { getGlobalContext } from 'vike'
const globalContext = await getGlobalContext()
// If you pre-render pages
console.log(globalContext.prerenderContext)
```

See:
- <Link href='#option-vikeconfig' />
- <Link href='#option-viteconfig' />
- <Link href='#access-globalcontext' />

Vite types:
- The type of `viteConfig` is [`ResolvedConfig`](https://vite.dev/guide/api-javascript.html#resolvedconfig)


## `preview()`

Start a server to preview the production build:

```ts
import { preview } from 'vike/api'

console.log('Starting preview server...')

const { viteConfig, viteServer } = await preview()
viteServer.printUrls()
viteServer.bindCLIShortcuts({ print: true })

const { port } = viteConfig.preview
console.log(`Preview server is ready at http://localhost:${port}`)
```

Return & options:

```ts
const {
  viteConfig, // Resolved Vite configuration
  viteServer // Vite's development server
} = await preview({
  vikeConfig, // Vike configuration (optional)
  viteConfig // Vite configuration (optional)
})

// You can access the globalContext object:
import { getGlobalContext } from 'vike'
const globalContext = await getGlobalContext()
```

See:
- <Link href='#option-vikeconfig' />
- <Link href='#option-viteconfig' />
- <Link href='#access-globalcontext' />

Vite types:
- The type of `viteConfig` is [`ResolvedConfig`](https://vite.dev/guide/api-javascript.html#resolvedconfig)
- Vite's preview server: [`const viteServer = preview()`](https://vite.dev/guide/api-javascript.html#preview)


## `prerender()`

<Link href="/pre-rendering">Pre-render</Link> pages (see <Link href="/prerender#disableautorun">`prerender.disableAutoRun`</Link>):

```ts
import { prerender } from 'vike/api'

console.log('Pre-rendering pages...')
await prerender()
console.log('Pre-rendering is done')
```

Return & options:

```ts
const {
  viteConfig // Resolved Vite configuration
} = await prerender({
  vikeConfig, // Vike configuration (optional)
  viteConfig, // Vite configuration (optional)
  pageContextInit, // Initial pageContext (optional)
  onPagePrerender // Called before writing an HTML file (optional)
})

// You can access the globalContext object:
import { getGlobalContext } from 'vike'
const globalContext = await getGlobalContext()
console.log(globalContext.prerenderContext)
```

See:
- <Link href='#option-viteconfig' />
- <Link href='#access-globalcontext' />
- <Link href='#option-vikeconfig' />
  > You can pass <Link href="/prerender">`+prerender` settings</Link> like this:
  > ```ts
  > await prerender({
  >   vikeConfig: {
  >     prerender: {
  >       keepDistServer: true,
  >       parallel: false
  >     }
  >   }
  > })
  > ```
- **`pageContextInit`**: Initial <Link href="/pageContext">`pageContext`</Link> values.
  ```ts
  prerender({
    pageContextInit: {
      someData: 42
      // ...
    }
  })
  ```
  > See also: <Link href="/pageContext#lifecycle" />.
- **`onPagePrerender()`**: control where/how HTML files are written.
  <Warning>This option is a beta feature: expect breaking changes in any minor version update.</Warning>
  ```ts
  prerender({
    // If onPagePrerender() is set, then Vike won't create HTML files
    onPagePrerender(pageContext) {
      // Custom logic for writing HTML files to the filesystem
      // ...
    }
  })
  ```

Vite types:
- The type of `viteConfig` is [`ResolvedConfig`](https://vite.dev/guide/api-javascript.html#resolvedconfig)


## Access `globalContext`

You can access the <Link href="/globalContext">`globalContext` object</Link> like this:

```ts
import { someApiFunction } from 'vike/api'
import { getGlobalContext } from 'vike'

await someApiFunction()
const globalContext = await getGlobalContext()
```

See: <Link href="/getGlobalContext" />


## Option `vikeConfig`

All API functions accept the option `vikeConfig` to pass <Link href="/settings">Vike settings</Link>.

> You can only pass serializable Vike settings (e.g. <Link href="/prerender">`+prerender`</Link> is serializable but <Link href="/Layout">`+Layout`</Link> isn't), and you cannot pass <Link href="/hooks">Vike hooks</Link>. (If you want to understand why, see <Link href="/error/runtime-in-config" /> and <Link href="/config#pointer-imports" />.)

> We generally recommend to define your Vike settings in your `pages/+config.js` file instead of using the `vikeConfig` option. The API automatically loads your `+config.js` files (just like the CLI).


## Option `viteConfig`

All API functions accept the option `viteConfig` (with type [`InlineConfig`](https://vitejs.dev/guide/api-javascript.html#inlineconfig)).

> We generally recommend to define your [Vite settings](https://vite.dev/config/) in your `vite.config.js` file instead of using the `viteConfig` option. The API automatically loads your `vite.config.js` file (just like the CLI).

If you want to define Vite settings outside of your app (typically when <Link href="/build-your-own-framework">building your own framework</Link>) you can do this:

```ts
import { dev } from 'vike/api'

await dev({
  viteConfig: {
    // vite.config.ts can live in node_modules/my-framework/src/vite.config.ts
    configFile: './path/to/vite.config.ts',
    // The app's root can be somewhere completely else than vite.config.ts
    root: './path/to/app/'
    // Some Vite settings overriding vite.config.ts
    /* ... */
  }
})
console.log('Development server is ready')
```

If you want to define your entire Vite config programmatically:

```ts
import { build } from 'vike/api'

await build({
  viteConfig: {
    // Don't load any vite.config.ts
    configFile: false
    // All Vite settings
    /* ... */
  }
})
console.log('Build is done')
```


## See also

- [Vite > JavaScript API](https://vite.dev/guide/api-javascript)
- <Link href="/cli" />
- <Link href="/build-your-own-framework" />
- <Link href="/createDevMiddleware" />
